TerraformでCodePipeline + CodeCommit作る際にトリガーでちょっとハマった話
「TerraformでCodePipelineを作ったが、ファイルの変更してもCodepipelineがトリガー(発火)してくれない」
TerraformでCodeCommitをソースとしたCodePipelineを作っていました。
コンソールからパイプラインの作成はできて、手動トリガーでの実行もできたのですがCodeCommitのファイル変更時にCodePipelineが発火してくれないことがありました。
結論から書くと、CodePipeline用のEventBridgeの定義の作成が漏れていました。 (マネジメントコンソール上からCodePipelineを作ると自動的に作成されます。)
少しはまったので、サンプルコードを含めてブログにします。
事象・原因
以下のようにCodepipelineを作成していました。 しかし、Codecommitでファイルを変更してもパイプラインが動きません。
resource "aws_codepipeline" "sample_app" { name = local.name_prefix role_arn = aws_iam_role.codepipeline.arn artifact_store { location = aws_s3_bucket.codepipeline_artifact.bucket type = "S3" } stage { name = "Source" action { name = "Source" category = "Source" owner = "AWS" provider = "CodeCommit" version = 1 output_artifacts = ["source_output"] configuration = { RepositoryName = aws_codecommit_repository.sample_app.repository_name BranchName = "main" OutputArtifactFormat = "CODE_ZIP" } } } stage { name = "Build" action { name = "Build" category = "Build" owner = "AWS" provider = "CodeBuild" version = 1 input_artifacts = ["source_output"] output_artifacts = ["build_output"] configuration = { ProjectName = aws_codebuild_project.sample_app.id } } } stage { name = "Deploy" action { name = "Deploy" category = "Deploy" owner = "AWS" provider = "ECS" version = 1 input_artifacts = ["build_output"] configuration = { ClusterName = aws_ecs_cluster.this.id ServiceName = aws_ecs_service.sample_app.name } } } }
マネジメントコンソールからソースアクションを見てみると、検出オプション「Amazon CloudWatch Events(推奨)」となっています。
この検出オプションでは、CodeCommitの変更イベントをEventBridge Rule(CloudWatch Events)で検出して、CodePipelineをターゲットにイベント送信を行います。 CodePipelineでは、イベントを受け取ってパイプラインの実行を開始します。
ここで、EventBridge Rule(CloudWatch Events)を作っていないことに気づきました。
ちなみに、マネジメントコンソールから手動でCodePipeline作成する場合、EventBridge Ruleは自動で生成されます。
解決策
EventBridge Ruleを追加します。
Terraform修正
マネジメントコンソールから作成時に自動で生成されるリソースを参考に、Terraform書いてみました。
resource "aws_codepipeline" "sample_app" { name = local.name_prefix role_arn = aws_iam_role.codepipeline.arn artifact_store { location = aws_s3_bucket.codepipeline_artifact.bucket type = "S3" } stage { name = "Source" action { name = "Source" category = "Source" owner = "AWS" provider = "CodeCommit" version = 1 output_artifacts = ["source_output"] configuration = { RepositoryName = aws_codecommit_repository.sample_app.repository_name BranchName = "main" OutputArtifactFormat = "CODE_ZIP" } } } stage { name = "Build" action { name = "Build" category = "Build" owner = "AWS" provider = "CodeBuild" version = 1 input_artifacts = ["source_output"] output_artifacts = ["build_output"] configuration = { ProjectName = aws_codebuild_project.sample_app.id } } } stage { name = "Deploy" action { name = "Deploy" category = "Deploy" owner = "AWS" provider = "ECS" version = 1 input_artifacts = ["build_output"] configuration = { ClusterName = aws_ecs_cluster.this.id ServiceName = aws_ecs_service.sample_app.name } } } } # cloudwatch event rule resource "aws_cloudwatch_event_rule" "codepipeline_sample_app" { name = "${local.name_prefix}-codepipeline-sample-app" event_pattern = templatefile("./file/codepipeline_event_pattern.json", { codecommit_arn : aws_codecommit_repository.sample_app.arn }) } resource "aws_cloudwatch_event_target" "codepipeline_sample_app" { rule = aws_cloudwatch_event_rule.codepipeline_sample_app.name arn = aws_codepipeline.sample_app.arn role_arn = aws_iam_role.event_bridge_codepipeline.arn }
resource "aws_iam_role" "event_bridge_codepipeline" { name = "${local.name_prefix}-event-bridge-codepipeline-role" assume_role_policy = data.aws_iam_policy_document.event_bridge_assume_role.json inline_policy { name = "codepipeline" policy = data.aws_iam_policy_document.event_bridge_codepipeline.json } } data "aws_iam_policy_document" "event_bridge_assume_role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["events.amazonaws.com"] } } } data "aws_iam_policy_document" "event_bridge_codepipeline" { statement { actions = ["codepipeline:StartPipelineExecution"] resources = ["${aws_codepipeline.sample_app.arn}"] } }
{ "source": ["aws.codecommit"], "detail-type": ["CodeCommit Repository State Change"], "resources": ["${codecommit_arn}"], "detail": { "event": ["referenceCreated", "referenceUpdated"], "referenceType": ["branch"], "referenceName": ["main"] } }
動作確認
上記をapply後CodeCommitに変更をコミットしたところ、CodePipelineが起動することを確認できました。
おわりに
似たような事象が発生した際の、参考になれば幸いです。
以上、AWS事業本部の佐藤(@chari7311)でした。